package us.icitap.timsportal.web;

import java.text.SimpleDateFormat;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import us.icitap.timsportal.ejb.PortalBeanLocal;
import us.icitap.timsportal.management.OfficerForm;
import us.icitap.timsportal.management.UserEditor;
import us.icitap.timsportal.management.UserForm;
import us.icitap.timsportal.management.UserSearch;
import us.icitap.timsportal.resources.TimsPortalLabels;
import us.icitap.timsportal.ui.ConfigMenu;
import us.icitap.timsportal.ui.LoginForm;
import us.icitap.timsportal.ui.ModuleMenu;
import us.icitap.timsportal.util.SessionHandler;
import us.icitap.timsportal.web.custom.LinkPortalButton;
import us.icitap.timsportal.ws.util.ADConnection;

import com.vaadin.Application;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class TimsPortalApp extends Application implements Button.ClickListener, HttpServletRequestListener  {
	
	private static final long serialVersionUID = 1L;
	
	private PortalBeanLocal portalBean;
	private SessionHandler sessionHandler;
	private ADConnection adConnection;
	private LinkPortalButton exitButton = new LinkPortalButton(TimsPortalLabels.getLabel("btn.exit"),(ClickListener)this);

	// Component Layouts
	private VerticalLayout layout = null;
	private HorizontalSplitPanel horizontalSplit = new HorizontalSplitPanel();
	private VerticalLayout body = new VerticalLayout();

	private CustomLayout footer = new CustomLayout("footer");
	
	
	// Lazely created ui references
	private LoginForm loginForm = null;
	private ModuleMenu moduleMenu = null;
	private ConfigMenu configMenu = null;
	private UserSearch userSearch = null;
	private UserEditor userEditor= null;
	private UserForm userForm = null;
	private OfficerForm officerForm = null;
	
	private Loader loader;
	
	public TimsPortalApp(PortalBeanLocal portalBean) {
		this.portalBean = portalBean;
		this.adConnection = new ADConnection();
		this.sessionHandler = new SessionHandler(portalBean, adConnection);
		loader = new Loader();
	}

	@Override
	public void init() {
		loader.loadLayout();
		loader.loadTimsPortal();
	}
	
	public UserSearch getUserSearch() {
		if(userSearch==null){
			userSearch = new UserSearch();
		}
		userSearch.clear();
		return userSearch;
	}
	
	public UserEditor getUserEditor(){
		if(userEditor==null){
			userForm = new UserForm();
			officerForm = new OfficerForm();
			userEditor = new UserEditor(userForm, officerForm);
		}
		return userEditor;
	}
	
	public void loadMainPage(){
		loader.loadTimsPortalMainPage();
	}
	 
	public void setMainComponent(Component c) {
        horizontalSplit.setSecondComponent(c);
    }
	
	public PortalBeanLocal getPortalBean(){
		return this.portalBean;
	}

	public SessionHandler getSessionHandler() {
		return this.sessionHandler;
	}

	@SuppressWarnings("serial")
	@WebServlet(urlPatterns = "/*")
	public static class Servlet extends AbstractApplicationServlet {
		
		@EJB
		PortalBeanLocal portalBean;

	    @Override
	    protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
	        return TimsPortalApp.class;
	    }


		@Override
		protected Application getNewApplication(HttpServletRequest request)
				throws ServletException {
			
			return new TimsPortalApp(portalBean);
		}
	}

	@Override
	public void buttonClick(ClickEvent event) {
		if (event.getButton() == exitButton) {
			WebApplicationContext webCtx = (WebApplicationContext) this
					.getContext();
			HttpSession session = webCtx.getHttpSession();
			session.invalidate();

			this.getMainWindow().open(new ExternalResource(this.getURL()));
		}
	}

	@Override
	public void onRequestStart(HttpServletRequest request,
			HttpServletResponse response) {
		
		boolean noQueryString = false;
		
		if(request.getSession().isNew()){
			noQueryString = request.getParameter("portalSessionId")==null;
			noQueryString = noQueryString || request.getParameter("moduleSessionId")==null;
			
			request.getSession(true).setAttribute("noQueryString", noQueryString);
			
			if(!noQueryString){
				request.getSession(true).setAttribute("portalSessionId", request.getParameter("portalSessionId"));
				request.getSession(true).setAttribute("moduleSessionId", request.getParameter("moduleSessionId"));
			}
			
		}
		
	}
	
	@Override
	public void onRequestEnd(HttpServletRequest request,
			HttpServletResponse response) {
		// TODO Auto-generated method stub
	}
	
	@Override
    public void close() {		
    }
	
	class Loader{
		
		public void loadLayout(){
			setMainWindow(new Window("Portali TIMS"));
			setTheme("my-runo");

			layout = (VerticalLayout) getMainWindow().getContent();
			layout.setMargin(false);
			layout.addStyleName("white");
			layout.addStyleName("logo");
			layout.setSizeFull();
			layout.addComponentAsFirst(new CustomLayout("header"));
			layout.addComponent(body);
			layout.addComponent(footer);
			layout.setExpandRatio(body, 2);
			getMainWindow().setContent(layout);
		}
		
		public void loadTimsPortal(){
			WebApplicationContext webCtx = (WebApplicationContext) getContext();
	        HttpSession session = webCtx.getHttpSession();
	        
			boolean validParams = false;
			
			if(!(Boolean)session.getAttribute("noQueryString")){
				validParams = !session.getAttribute("portalSessionId").toString().equals("");
				validParams = validParams && !session.getAttribute("moduleSessionId").toString().equals("");
			}
			
			if(validParams){
				boolean noError = loadTimsPortal(
						session.getAttribute("portalSessionId").toString(),
						session.getAttribute("moduleSessionId").toString());
				if(!noError){
					sessionHandler.showErrorMessage();
					return;
				}
			} else {
				boolean noError = loadTimsPortalLoginPage();
				if(!noError){
					sessionHandler.showErrorMessage();
					return;
				}
			}
			
		}
		
		public boolean loadTimsPortal(String previousPortalSessionId, String moduleSessionId){
			try {
				boolean noError = sessionHandler.searchUserSessionInDB(previousPortalSessionId, moduleSessionId);
				if(!noError){
					sessionHandler.showErrorMessage();
					return false;
				}
				if(sessionHandler.isPortalUserAuthenticated() 
						&& !sessionHandler.isOpenPortalSession()){
					String portalSessionId = ((WebApplicationContext)getContext()).getHttpSession().getId();
					sessionHandler.reloadSessionHandler(previousPortalSessionId,portalSessionId, moduleSessionId);
					
					setUser(sessionHandler.getUser());
					sessionHandler.checkUserRoles();
					loadTimsPortalMainPage();				
				} else loadTimsPortalLoginPage();
				return true;
			} catch (Exception e) {
				sessionHandler.setErrorMessage(e.getMessage());
				return false;
			}
		}
		
		public boolean loadTimsPortalLoginPage(){
			try {
				layout.replaceComponent(layout.getComponent(1), getLoginForm());
	        	layout.setExpandRatio(getLoginForm(), 1);
				return true;
			} catch (Exception e) {
				sessionHandler.setErrorMessage(e.getMessage());
				return false;
			}
		}
		
		public boolean loadTimsPortalMainPage(){
			try {
				layout.replaceComponent(layout.getComponent(1), horizontalSplit);
	        	layout.setExpandRatio(horizontalSplit, 1);
	        	
	        	horizontalSplit.setSplitPosition(200, HorizontalSplitPanel.UNITS_PIXELS);
	        	horizontalSplit.setFirstComponent(getLeftPanel());
	        	horizontalSplit.setLocked(true);
	        	horizontalSplit.setStyleName("invisible");

	        	body = new VerticalLayout();
	        	body.setSizeFull();        	
	        	horizontalSplit.setSecondComponent(body);
	        	
	        	footer.addComponent(new Label(sessionHandler.getUsername()), "username");
	        	footer.addComponent(new Label("Hyrja: "), "entryTimeLabel");
	        	footer.addComponent(new Label(new SimpleDateFormat("dd.MM.yyyy hh:mm").format(portalBean.getSysdate())), "entryTime");
	        	return true;			
			} catch (Exception e) {
				sessionHandler.setErrorMessage(e.getMessage());
				return false;
			}
			
		}
		
		private LoginForm getLoginForm(){
			if(loginForm == null){
				loginForm = new LoginForm();
			}
			return loginForm;
		}
		
		
		private VerticalLayout getLeftPanel() {			
			VerticalLayout vl = new VerticalLayout();
			vl.setStyleName("menu");
			vl.setWidth("80%");
			moduleMenu = new ModuleMenu();
			vl.addComponent(moduleMenu);
			configMenu = new ConfigMenu();
			vl.addComponent(configMenu);
			vl.addComponent(exitButton);
					
			return vl;
		}
		
	}

	public ADConnection getAdConnection() {
		return adConnection;
	}

}


